import { ElMessage as message } from 'element-plus';

import axios from 'axios';
import Emitter from 'tiny-emitter';

const ev = new Emitter();
const catchNum = {};
let i = 0;
function generateReqKey(config) {
  let { method, url, params, data } = config;
  let tmpData = data;
  if (data instanceof FormData) {
    tmpData = i++;
  }
  return JSON.stringify([method, url, params, tmpData]);
}

const request = async (config) => {
  let cacheKey = generateReqKey(config);

  // config.url = '/api-c1' + config.url;

  try {
    let flag = catchNum[cacheKey] !== undefined;

    if (flag) {
      catchNum[cacheKey]++;
      return await new Promise((resolve, reject) => {
        ev.once(cacheKey, ({ type, data, error }) => {
          if (type === 'success') {
            resolve(data);
          } else {
            reject(error);
          }
        });
      });
    } else {
      catchNum[cacheKey] = 0;
      let res = await axios(config);

      if (config.download && res.data?.success != false) {
        if (catchNum[cacheKey]) {
          ev.emit(cacheKey, { type: 'success', data: res });
        }
        delete catchNum[cacheKey];
        return res;
      }
      if (res.data.code == 1) {
        let data = res.data.data;
        if (catchNum[cacheKey]) {
          ev.emit(cacheKey, { type: 'success', data: JSON.parse(JSON.stringify(data)) });
        }
        delete catchNum[cacheKey];
        return data;
      }

      throw res.data;
    }
  } catch (error) {
    console.error(error);
    if (catchNum[cacheKey]) {
      ev.emit(cacheKey, { type: 'fail', error });
    }
    delete catchNum[cacheKey];
    ev.emit(cacheKey, { type: 'fail', error });
    if (!config.hideMessage) {
      let msg =
        error.errorMessage ||
        error.response?.data?.message ||
        error.response?.data?.error ||
        '系统繁忙，请稍后再试';
      if (msg) {
        message.error(msg);
      }
    }
    throw error;
  }
};
const post = (url, data, config) => request({ url, method: 'post', data, ...config });
const get = (url, params, config) => request({ url, method: 'get', params, ...config });

const req = {
  request,
  post,
  get,
};

export default req;
